/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import java.io.*;
import java.net.*;

import netPacks.*;

/**
 *
 * @author user
 */
public class backupServer extends Thread{
    
	ServerSocket localBackupServer = null;
	Socket backupSocket = null;
	Socket remoteCon = null;
	InetAddress backupHost = null;
    ObjectInputStream bOis = null;
    ObjectOutputStream bOos = null;
	int backupPort = 0;
	int localServerPort = 0;
	message msg = null;
	int CHECK_INTERVAL = 10000;
	int timePassed = 0;
	scoreBoard sb = null;
	
    private static volatile backupServer instance = null;
	
    private backupServer(InetAddress backup, int port){
        this.msg = new message();
        this.msg.setAction("backupStatus");
        try {
			msg.setUserId(InetAddress.getLocalHost());
		} 
        catch (UnknownHostException e1) {
        	System.err.println("Cannot aquire local IP address:\n" + e1.getMessage());
		}
    	this.backupHost = backup;
    	this.backupPort = port;
    }
    
    public static backupServer getInstance(InetAddress backup, int port) {
        if (instance == null){
            synchronized (backupServer.class){
                    if (instance == null){
                        instance = new backupServer(backup, port);
                    }
            }
        }
        return instance;
    }
	
	public synchronized void run(){
		if(!mainServer.getInstance().isBackup){
			try {
				this.backupSocket = new Socket(this.backupHost, this.backupPort);
				this.bOos = new ObjectOutputStream(this.backupSocket.getOutputStream());
				bOos.flush();
				this.bOis = new ObjectInputStream(this.backupSocket.getInputStream());
			}
			catch (IOException e) {
				System.err.println("Cannot establish connection with Backup server via socket.\n"+e.getMessage());
			}
			while(true){
				if(!mainServer.getInstance().isBackup){
					try {
						this.bOos.writeObject(msg);
					} 
					catch (IOException e) {
						System.err.println("Backup socket may be closed.\n"+e.getMessage());
					}
					
					try{
						Thread.sleep(CHECK_INTERVAL);
					} 
					catch (InterruptedException e) {
						e.printStackTrace();
					}
					this.timePassed +=CHECK_INTERVAL;
					
					if(this.timePassed == 60000){
						sb = scoreBoard.getInstance();
						try {
							this.bOos.writeObject(sb);
							System.out.println("Scoreboard backup sent.");
						} 
						catch (IOException e) {
							System.err.println("Cannot send scoreboard backup.\n"+e.getMessage());
						}
					}
				}
				else{
					break;
				}
			}
		}

		else if(mainServer.getInstance().isBackup){
			try {
				this.localBackupServer = new ServerSocket(this.localServerPort);
			}
			catch (IOException e) {
				System.err.println("Cannot initialize backup server socket.\n"+e.getMessage());
			}
			
			try {
				this.localBackupServer.setSoTimeout(5000);
			} 
			catch (SocketException e) {
				System.err.println("Cannot set timeout on ServerSocket for backup.\n"+e.getMessage());
			}

			try{
				this.remoteCon = localBackupServer.accept();
				this.bOos = new ObjectOutputStream(this.remoteCon.getOutputStream());
				bOos.flush();
				this.bOis = new ObjectInputStream(this.remoteCon.getInputStream());
			}
			catch(SocketTimeoutException toe){
				System.err.println("Server backup connection has not been established for ten minutes.\n"+toe.getMessage());
			}
			catch(IOException ioe){
				System.err.println("Backup server cannot listen and accept connections.\n"+ioe.getMessage());
			}
		}
	}
}
